/** @hidden */
module.exports = function patchPTYModule (mod) {
    const oldSpawn = mod.spawn
    if (mod.patched) {
        return
    }
    mod.patched = true
    mod.spawn = (file, args, opt) => {
        let terminal = oldSpawn(file, args, opt)
        let timeout = null
        let buffer = Buffer.from('')
        let lastFlush = 0
        let nextTimeout = 0

        // Minimum prebuffering window (ms) if the input is non-stop flowing
        const minWindow = 5

        // Maximum buffering time (ms) until output must be flushed unconditionally
        const maxWindow = 100

        function flush () {
            if (buffer.length) {
                terminal.emit('data-buffered', buffer)
            }
            lastFlush = Date.now()
            buffer = Buffer.from('')
        }

        function reschedule () {
            if (timeout) {
                clearTimeout(timeout)
            }
            nextTimeout = Date.now() + minWindow
            timeout = setTimeout(() => {
                timeout = null
                flush()
            }, minWindow)
        }

        terminal.on('data', data => {
            if (typeof data === 'string') {
                data = Buffer.from(data)
            }
            buffer = Buffer.concat([buffer, data])
            if (Date.now() - lastFlush > maxWindow) {
                // Taking too much time buffering, flush to keep things interactive
                flush()
            } else {
                if (Date.now() > nextTimeout - maxWindow / 10) {
                    // Extend the window if it's expiring
                    reschedule()
                }
            }
        })
        return terminal
    }
}
